package com.mulanweb.handler.wechat;

import com.mulanweb.api.module.model.*;
import com.mulanweb.db.common.Constant;
import com.mulanweb.db.common.RandomStringGenerator;
import com.mulanweb.db.common.WxParaFormatter;
import com.mulanweb.handler.CouponHandler;
import com.mulanweb.handler.PostHandler;
import com.mulanweb.utils.DateUtil;
import com.mulanweb.utils.RandomUtil;
import com.mulanweb.utils.WxSignUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.xml.sax.SAXException;

import javax.net.ssl.SSLContext;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by Administrator on 2016/11/17 0017.
 */
public class PaymentSeller {

    /**
     * 用户对商家的付款，付款成功保存到付款历史表中，失败保存到错误记录表中
     *
     * @param orderNumber 商户订单号
     * @param openId      微信用户主键
     * @param name        用户真实姓名
     * @param amount      金额（单位为分）
     */
    public static void paymentSeller(String orderNumber, String openId, String name, Integer amount) {
        String url = Constant.WeChatFinalValue.WECHAT_PAYMENT_USER;

        SortedMap<Object, Object> para = new TreeMap<Object, Object>();
        para.put("mch_appid", Constant.WeChatFinalValue.APPID);
        para.put("mchid", Constant.WeChatFinalValue.MCHID);
        para.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
        para.put("partner_trade_no", orderNumber);
        para.put("openid", openId);
        para.put("check_name", "NO_CHECK");
        para.put("amount", amount + "");
        para.put("desc", "体验者活动返现。");
        para.put("spbill_create_ip", "121.199.77.244");
        String sign = WxSignUtil.createGetPrepayIdSign(para);
        para.put("sign", sign);

        String xml = WxParaFormatter.getRequestXml(para);
        try {
            //指定格式读取证书格式为PKCS12
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            //读取本机存放的证书文件
            FileInputStream instream = new FileInputStream(new File(Constant.ContextPatameter.PAY_CERTIFICATE_URL));
            try {
                //指定PKCS12的密码(商户ID)
                keyStore.load(instream, Constant.WeChatFinalValue.MCHID.toCharArray());
            } finally {
                instream.close();
            }

            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, Constant.WeChatFinalValue.MCHID.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[]{"TLSv1"},
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();


            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost post = new HttpPost(url);
            post.addHeader("Content/Type", "application/xml");
            StringEntity stringEntity = new StringEntity(xml, ContentType.create("application/xml", "UTF-8"));
            post.setEntity(stringEntity);
            CloseableHttpResponse resp = null;
            try {
                resp = httpclient.execute(post);
            } catch (IOException e) {
                e.printStackTrace();
            }
            int returnCode = resp.getStatusLine().getStatusCode();
            String str = "";
            if (200 <= returnCode && 300 >= returnCode) {
                try {
                    str = (EntityUtils.toString(resp.getEntity()));
                    Map<String, String> result = WxParaFormatter.xmlToMap(str);
                    if ("SUCCESS".equals(result.get("return_code"))
                            && result.containsKey("result_code")
                            && "SUCCESS".equals(result.get("result_code"))) {
                        Order order = Order.dao.findFirst("SELECT * FROM `order` WHERE order_number =?", orderNumber);
                        HistoryPaymentSeller payment = HistoryPaymentSeller.dao.findFirst("SELECT * FROM history_payment_seller WHERE partner_trade_no=? AND payment_no=?"
                                , order.getOrderNumber(), result.get("payment_no"));
                        if (!(payment != null)){
                            payment = new HistoryPaymentSeller();
                            payment.setOpenId(openId);
                            payment.setSellerId(order.getSellerId());
                            payment.setPartnerTradeNo(orderNumber);
                            payment.setPaymentNo(result.get("payment_no"));
                            payment.setVerifyName(name);
                            payment.setAmount(amount);
                            payment.setDesc("系统自动转账成功，对象为：" + name);
                            payment.setCreateTime(new Date());
                            payment.setPaymentTime(DateUtil.strToDate(result.get("payment_time"), "yyyy-MM-dd HH:mm:ss"));
                            payment.setCreateTime(new Date());
                            payment.save();
                        }
                    } else {
                        ErrorPaymentSeller error = new ErrorPaymentSeller();
                        error.setErrorCode(result.get("err_code"));
                        error.setErrorDesc(result.get("return_msg") + "---" + result.get("err_code_des"));
                        error.setPartnerTradeNo(orderNumber);
                        error.setCreateTime(new Date());
                        error.save();
                    }
                    System.out.println(result);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            ErrorPaymentSeller error = new ErrorPaymentSeller();
            error.setErrorCode("500");
            error.setErrorDesc("打款至商家时遇到一个未知的问题,请联系管理员查收，谢谢");
            error.setPartnerTradeNo(orderNumber);
            error.setCreateTime(new Date());
            error.save();
            e.printStackTrace();
        }
    }


    public static Boolean refundToUser(String orderNumber, Float amount) throws Exception {

        String queryRefund = Constant.WeChatFinalValue.WECHAT_QUERY_REFUND_USER;//查询退款地址
        String url = Constant.WeChatFinalValue.WECHAT_REFUND_USER; //退款地址

        SortedMap<Object, Object> para = new TreeMap<Object, Object>();
        para.put("appid", Constant.WeChatFinalValue.APPID);
        para.put("mch_id", Constant.WeChatFinalValue.MCHID);
        para.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));
        para.put("out_trade_no", orderNumber);
        para.put("out_refund_no",orderNumber);
        para.put("total_fee", (int)(amount*100));//化元为分
        para.put("refund_fee", (int)(amount*100));
        para.put("op_user_id", "admin");
        String sign = WxSignUtil.createGetPrepayIdSign(para);
        para.put("sign", sign);
        String xml = WxParaFormatter.getRequestXml(para);

        Map<String, String> map = PostHandler.post(queryRefund, xml, "application/xml");

        if (map.containsKey("return_code")
                && "SUCCESS".equals(map.get("return_code"))
                && map.containsKey("result_code")
                && "SUCCESS".equals(map.get("result_code"))
                && map.containsKey("refund_status_0")
                && "SUCCESS".equals(map.get("refund_status_0"))) {
            //退款成功;
            return false;
        }

        try {
            //指定格式读取证书格式为PKCS12
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            //读取本机存放的证书文件
            FileInputStream instream = new FileInputStream(new File(Constant.ContextPatameter.PAY_CERTIFICATE_URL));
            try {
                //指定PKCS12的密码(商户ID)
                keyStore.load(instream, Constant.WeChatFinalValue.MCHID.toCharArray());
            } finally {
                instream.close();
            }

            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, Constant.WeChatFinalValue.MCHID.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[]{"TLSv1"},
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();


            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost post = new HttpPost(url);
            post.addHeader("Content/Type", "application/xml");
            StringEntity stringEntity = new StringEntity(xml, ContentType.create("application/xml", "UTF-8"));
            post.setEntity(stringEntity);
            CloseableHttpResponse resp = null;
            try {
                resp = httpclient.execute(post);
            } catch (IOException e) {
                e.printStackTrace();
            }
            int returnCode = resp.getStatusLine().getStatusCode();
            String str = "";
            if (200 <= returnCode && 300 >= returnCode) {
                str = (EntityUtils.toString(resp.getEntity(), "UTF-8"));
                Map<String, String> result = WxParaFormatter.xmlToMap(str);
                if ("SUCCESS".equals(result.get("return_code"))
                        && result.containsKey("result_code")
                        && "SUCCESS".equals(result.get("result_code"))) {
                    Order order = Order.dao.findFirst("SELECT * FROM `order` WHERE order_number=?",orderNumber);
                    order.setStatusId(9L);//设置订单已退款状态
                    order.setVerifyCodeStatus(16L);//设置验证码已失效状态
                    order.update();
                    //订单已退款，优惠券恢复库存
                    CouponHandler.cancelCoupon(order.getCouponId());
                    String openId = User.dao.findById(order.getUserId()).getOpenId();
                    String contentName = Ticket.dao.findById(order.getTargetId()).getTitle();
                    SentModelMessageHandler.sentRefundModel(openId,order.getAmount()*order.getUnitPrice()- CouponHandler.getCouponValue(order.getCouponId()),order.getOrderNumber(),contentName);
                    return true;
                }else{
                    return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
